package co.edu.udea.iw.prestamos.modelo.dao.hibernate;

import java.util.List;

import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import co.edu.udea.iw.prestamos.modelo.dao.UsuarioDAO;
import co.edu.udea.iw.prestamos.modelo.dto.Usuario;
import co.edu.udea.iw.prestamos.util.exception.UserNotFoundException;

/**
 * DAO usando el framework Hibernate para manejar los objetos Usuario
 * @author Santiago Álvarez Rodríguez <santiaro90@gmail.com>
 * @since 07-07-2014
 * @version 1.0
 */
@Repository("usuarioDao")
public class UsuarioDAOHibernate extends CrudDAOHibernate<Usuario, String>
	implements UsuarioDAO {

	public UsuarioDAOHibernate() {
		super(Usuario.class);
	}
	
	/**
	 * @see UsuarioDAO#obtenerUsuarioPorUsername(String)
	 */
	@Override
	@Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
	public Usuario obtenerUsuarioPorUsername(String nombreUsuario)
			throws UserNotFoundException {
		
		// Buscamos el usuario en la BD
		Usuario usuario = (Usuario) getCurrentSession()
				.createCriteria(Usuario.class)
				.add(Restrictions.eq("nombreUsuario", nombreUsuario))
				.uniqueResult();
		
		// Si no hay resultado, lanzamos la excepción
		if (usuario == null) {
			String msjExcepcion = "El nombre de usuario dado no existe";
			throw new UserNotFoundException(msjExcepcion);
		}
		
		return usuario;
	}

	/**
	 * @see UsuarioDAO#obtenerUsuarioPorEmail(String)
	 */
	@Override
	@Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
	public Usuario obtenerUsuarioPorEmail(String email)
			throws UserNotFoundException {
		
		// Buscamos el usuario en la BD
		Usuario usuario = (Usuario) getCurrentSession()
				.createCriteria(Usuario.class)
				.add(Restrictions.eq("email", email))
				.uniqueResult();
		
		// Si no hay resultado, lanzamos la excepción
		if (usuario == null) {
			String msjExcepcion = "El nombre de usuario dado no existe";
			throw new UserNotFoundException(msjExcepcion);
		}
		
		return usuario;
	}

	/**
	 * @see UsuarioDAO#obtenerInvestigadores()
	 */
	@SuppressWarnings("unchecked")
	@Override
	@Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
	public List<Usuario> obtenerInvestigadores() {
		
		// Hacemos Join entre Usuario y Rol para obtener la descripción
		// del rol de cada usuario
		return getCurrentSession()
				.createCriteria(Usuario.class, "usuario")
				.createAlias("usuario.rol", "rol")
				.add(Restrictions.eq("rol.descripcion", "Investigador"))
				.list();
	}
	
	
			
}
